package com.template.utils.redis;

import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 本质是基于 String 类型的位操作
 */
@Component
public class BitmapOps extends KeyOps {

    private final ValueOperations<String, Object> stringOperations;

    public BitmapOps(RedisTemplate<String, Object> redisTemplate) {
        super(redisTemplate);
        this.stringOperations = redisTemplate.opsForValue();
    }

    /**
     * <h4> Bitmap </h4>
     * 将二进制第 offset 位值变为 value
     * <li> setbit _key _offset _value </li>
     */
    public Boolean setBit(String key, long offset, boolean value) {
        return stringOperations.setBit(key, offset, value);
    }

    /**
     * <h4> Bitmap </h4>
     * 对 key 所储存的字符串值，获取指定偏移量上的位(bit)
     * <li> getbit _key _offset </li>
     */
    public Boolean getBit(String key, long offset) {
        return stringOperations.getBit(key, offset);
    }


    /**
     * <h4> Bitmap </h4>
     * 统计字节数占用多少
     * <li> strlen _key </li>
     */
    public Long strlen(String key) {
        return stringOperations.size(key);
    }

    /**
     * <h4> Bitmap </h4>
     * 所有位上为 1 的个数
     * <li> bitcount _key </li>
     */
    public Long bitCount(String key) {
        return redisTemplate.execute((RedisCallback<Long>) conn -> conn.bitCount(key.getBytes()));
    }

    /**
     * <h4> Bitmap </h4>
     * 位上为 1 的个数
     * <li> bitcount _key _offset _ </li>
     */
    public List<Long> bitField(String key, BitFieldSubCommands commands) {
        return stringOperations.bitField(key, commands);
    }
}
